package com.ekingstar.lss.commons.utils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


import com.ekingstar.lss.commons.exceptions.QueryUtilsException;
import com.ekingstar.lss.commons.supper.utils.query.LssCondition;
import com.ekingstar.lss.commons.supper.utils.query.LssCount;
import com.ekingstar.lss.commons.supper.utils.query.LssGroup;
import com.ekingstar.lss.commons.supper.utils.query.LssOrder;
import com.ekingstar.lss.commons.supper.utils.query.LssTarget;
import com.ekingstar.lss.commons.supper.utils.query.simple.SimpleCondition;
import com.ekingstar.lss.commons.supper.utils.query.simple.SimpleCount;
import com.ekingstar.lss.commons.supper.utils.query.simple.SimpleGroup;
import com.ekingstar.lss.commons.supper.utils.query.simple.SimpleOrder;
import com.ekingstar.lss.commons.supper.utils.query.simple.SimpleTarget;

/**
 *	公司：金仕达多媒体
 *	作者：童弘成
 *	时间：2011-4-20 下午05:57:23
 *	描述：处理query对象的数据的转换。
 */
public class QueryUtils {
	
	public final static Pattern wordfind=Pattern.compile("([^A-Za-z0-9 \\f\\n\\r\\t\\v]|\\w+)");
	public final static Pattern ifstr=Pattern.compile("^and|or$");
	
	public final static Pattern countstr=Pattern.compile("^(count|sum|avg|max|min)\\(\\S+\\)$");
	
	public static List<String> parseColumns(String content){
		content=content.replaceAll("\\s+", " ").trim().toLowerCase();
		List<String> list=new ArrayList<String>();
		int ts=content.indexOf("select");
		int te=content.indexOf("from");
		StringBuffer columns=new StringBuffer();
		if(ts!=-1&&te!=-1){
			columns.append(content.substring(ts+"select".length(),te).trim());
		}else{
			throw new QueryUtilsException("查询语句语法不正确");
		}
		String[] columnsArray=columns.toString().split(",");
		for (int i = 0; i < columnsArray.length; i++) {
			list.add(columnsArray[i].replaceAll("\\s+", " ").trim());
		}
		return list;
	}
	
	public static LssTarget parseTarget(String content){
		content=content.replaceAll("\\s", " ").trim().toLowerCase();
		String target="";
		if(content.indexOf("where")!=-1){
			target=content.substring(content.indexOf("from")+"from".length(),content.indexOf("where"));
		}else if(content.indexOf("group")!=-1){
			target=content.substring(content.indexOf("from")+"from".length(),content.indexOf("group"));
		}else if(content.indexOf("order")!=-1){
			target=content.substring(content.indexOf("from")+"from".length(),content.indexOf("order"));
		}else{
			target=content.substring(content.indexOf("from"),content.length());
		}
		return new SimpleTarget(target.trim()) ;
	}
	
	public static List<LssCondition> parseCondition(String content,List<Object> params){
		List<LssCondition> conditions=new ArrayList<LssCondition>();
		String tpthycontent=content.trim();
		tpthycontent=tpthycontent.replaceAll("\\s+", " ").toLowerCase();
		if(tpthycontent.indexOf("where")==-1){
			throw new QueryUtilsException("无条件语句");
		}
		String conditionstr="";
		if(tpthycontent.indexOf("group")!=-1){
			conditionstr=tpthycontent.substring(tpthycontent.indexOf("where")+"where".length(),tpthycontent.indexOf("group")).trim();
			
		}else if(tpthycontent.indexOf("order")!=-1){
			conditionstr=tpthycontent.substring(tpthycontent.indexOf("where")+"where".length(),tpthycontent.indexOf("order")).trim();
		}else{
			conditionstr=tpthycontent.substring(tpthycontent.indexOf("where")+"where".length(),tpthycontent.length()).trim();
		}
		parseCondition(conditionstr, conditions, 0,params.iterator());
		return conditions;
	}
	
	private static int parseCondition(String constr,List<LssCondition> conditions,int start,Iterator<Object> params){		
		Matcher m=wordfind.matcher(constr);
		boolean res=m.find(start);
		SimpleCondition condition=new SimpleCondition();
		List<Object> lssparams=new ArrayList<Object>();
		StringBuffer content=new StringBuffer();
		condition.setType("and");
		while(res){
			int ts=m.start();
			int te=m.end();
			String cstr=constr.substring(ts,te);
			start=te;
//			System.out.println("ffffffffffff "+cstr);
			if("(".equals(cstr)){
				List<LssCondition> ccon=new ArrayList<LssCondition>();
				start=parseCondition(constr, ccon, te, params);
				condition.setConditions(ccon);
				conditions.add(condition);
				condition=new SimpleCondition();
				cstr=")";
			}else if(")".equals(cstr)){
				condition.setContent(content.toString().trim());
				condition.setValues(lssparams);
				if(condition.getType()!=null){
					conditions.add(condition);
				}
				return te;
			}else if(ifstr.matcher(cstr).matches()){
				condition.setContent(content.toString().trim());
				condition.setValues(lssparams);
				conditions.add(condition);
				lssparams=new ArrayList<Object>();
				condition=new SimpleCondition();
				condition.setType(cstr);
				content=new StringBuffer();
			}else if("?".equals(cstr)){
				Object obj=params.next();
				lssparams.add(obj);
				content.append("").append(cstr);
			}else{
				content.append("").append(cstr);
			}
			
			if(start>=constr.length()){
				if(")".equals(cstr)){
					break;
				}
				condition.setContent(content.toString());
				condition.setValues(lssparams);
				conditions.add(condition);
				break;
			}
			res=m.find(start);
		}
		return start;
	}
	
	public static List<LssGroup> parseGroups(String content){
		List<LssGroup> groups=new ArrayList<LssGroup>();
		String tpthycontent=content.trim();
		tpthycontent=tpthycontent.replaceAll("\\s+", " ").toLowerCase();
		if(tpthycontent.indexOf("group by")==-1){
			throw new QueryUtilsException("无分组语句");
		}
		String groupsstr="";
		if(tpthycontent.indexOf("order")!=-1){
			groupsstr=tpthycontent.substring(tpthycontent.indexOf("group by")+"group by".length(),tpthycontent.indexOf("order")).trim();
		}else{
			groupsstr=tpthycontent.substring(tpthycontent.indexOf("group by")+"group by".length(),tpthycontent.length()).trim();
		}
		String[]gourpsarray=groupsstr.split(",");
		for (int i = 0; i < gourpsarray.length; i++) {
			groups.add(new SimpleGroup(gourpsarray[i].replaceAll("\\s+", "")));
		}
		return groups;
	}
	
	public static List<LssOrder> parseOrders(String content){
		List<LssOrder> orders=new ArrayList<LssOrder>();
		String tpthycontent=content.trim();
		tpthycontent=tpthycontent.replaceAll("\\s+", " ").toLowerCase();
		String ordersstr=tpthycontent.substring(tpthycontent.indexOf("order by")+"group by".length(),tpthycontent.length()).trim();
		String[]ordersarray=ordersstr.split(",");
		for (int i = 0; i < ordersarray.length; i++) {
			orders.add(new SimpleOrder(ordersarray[i]));
		}
		return orders;
	}
	
	public static List<LssCount> parseCount(String content){
		List<LssCount> counts=new ArrayList<LssCount>();
		List<String> columns=parseColumns(content);
		for (int i = 0; i < columns.size(); i++) {
			String columnstr=columns.get(i).trim();
			if(countstr.matcher(columnstr).matches()){
				SimpleCount lsscount=new SimpleCount(columnstr);
				counts.add(lsscount);
			}
		}
		return counts;
	}
}
